package com.itheima.springboottilasmanager.survice.deptsurvice;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.bcript.BCryptUtil;
import com.itheima.springboottilasmanager.Exception.UsernotexistException;
import com.itheima.springboottilasmanager.anonotation.Time;
import com.itheima.springboottilasmanager.mapper.DeptMapper;
import com.itheima.springboottilasmanager.mapper.EmpExprMapper;
import com.itheima.springboottilasmanager.mapper.EmpLogMapper;
import com.itheima.springboottilasmanager.mapper.EmpMapper;
import com.itheima.springboottilasmanager.pojo.domain.*;
import com.itheima.springboottilasmanager.pojo.vo.QueryParam;
import com.itheima.springboottilasmanager.survice.DeptSurvice;
import com.itheima.springboottilasmanager.survice.EmpLogService;
import com.itheima.springboottilasmanager.survice.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class EmpS extends ServiceImpl<EmpMapper, Emp> implements EmpService {


    @Autowired
    private EmpMapper emp;

    @Autowired
    private EmpExprMapper empx;

    @Autowired
    private EmpLogService empLogService;

    @Autowired
    private BCryptUtil bCryptUtil;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpExprServiceIml empExprService;

    @Transactional
    @Override
    public PageResult<Emp> page(QueryParam queryParam) {
//        使用分页插件
//        PageHelper.startPage(queryParam.getPage(), queryParam.getPageSize());
//        1.查询员工数据
//   返回page对象
//   List<Emp> list =  emp.page(queryParam);
//        Page<Emp> page = (Page<Emp>) emp.selectByCondition(queryParam);
//   对其封装
        // 调用 mapper
//        Page<Emp> page = (Page<Emp>) emp.page(queryParam);
//        PageResult<Emp> pageResult = new PageResult<>();
//        pageResult.setTotal(page.getTotal());
//        pageResult.setRows(page.getResult());
//        return pageResult;
//   1.创建封装分页信息的page对象功能：1.封装分页参数2.封装分页结果
        Page<Emp> page = Page.of(queryParam.getPage(), queryParam.getPageSize());

        LambdaQueryWrapper<Emp> wrapper = new LambdaQueryWrapper<Emp>()
                .like(queryParam.getName() != null, Emp::getName, queryParam.getName())
                .eq(queryParam.getGender()!=null,Emp::getGender, queryParam.getGender())
                .between(queryParam.getBegin()!=null,Emp::getEntryDate, queryParam.getBegin(), queryParam.getEnd());
        //   2.调用分页功能方法

        page = page(page,wrapper);
//        如果员工列表不为空

        //           获取所有员工的部门ID
        //对当前页页数据列表List<Emp>封装部门名称
        List<Emp> empList = page.getRecords();
        //CollectionUtil 是hutool工具类
        if(CollectionUtil.isNotEmpty(empList)) {
            //实现思路：不要一个一个员工去封装查询部门，因为很多部门是重复的
            //         将员工里面部门id抽取出来封装成List<Integer> deptIds
            List<Integer> deptIds = empList.stream().map(Emp::getDeptId).toList();
            //         根据部门deptIds查询部门列表
            List<Dept> deptList = deptMapper.selectBatchIds(deptIds);
            if(CollectionUtil.isNotEmpty(deptList)) {
                //遍历员工empList，封装每个员工的部门名称
                empList.forEach(emp->{
                    deptList.stream().filter(dept->dept.getId().equals(emp.getDeptId())).findFirst().
                            ifPresent(dept->emp.setDeptName(dept.getName()));
                });
            }
        }


   return new PageResult<>(page.getTotal(), page.getRecords());
    }


//

    @Transactional
    @Override
    public void saveEmp(Emp emp1) {
        try {
            // 1. 添加员工
            emp1.setCreateTime(LocalDateTime.now());
            emp1.setUpdateTime(LocalDateTime.now());

            emp1.setPassword(bCryptUtil.hashPassword("123456"));
//            emp.insert(emp1);
            save(emp1);
            log.info("添加员工信息：{}", emp1);

            // 2. 添加工作经历
            List<EmpExpr> exprList = emp1.getExprList();
            if (exprList != null && !exprList.isEmpty()) {
                exprList.forEach(expr -> expr.setEmpId(emp1.getId()));
                empExprService.saveBatch(exprList); // 记得确认 insertBatch 是否可用
            }

            // 3. 成功日志（主事务成功时写）
            empLogService.insertLog(new EmpLog(emp1.getId(), LocalDateTime.now(), "添加员工成功：" + emp1));

        } catch (Exception e) {
            log.error("保存员工失败", e);
            // 失败日志（无论主事务回滚，这里仍然能保存）
            empLogService.insertLog(new EmpLog(emp1.getId(), LocalDateTime.now(), "添加员工失败：" + e.getMessage()));
            throw e; // 保证主事务回滚
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    @Time
    public void deleteEmp(List<Integer> ids) {
        removeBatchByIds(ids);
        empExprService.removeBatchByIds(ids);
    }
    @Override
    public Emp findById(Integer id) {
        Emp emp2 = emp.selectById(id);
        return emp2;
    }
@Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEmp(Emp emp1) {
//提前考虑清楚：涉及到几张表

//        1.更新员工表
        updateEmp(emp1);
//        2.更新员工工作尽力表

//        2.1先删除
        empExprService.removeBatchByIds(Arrays.asList(emp1.getId()));
//        2.2后添加
//        设置新增的工作经历鬼书的员工ID
//        emp1.getExprList().forEach(expr -> expr.setEmpId(emp1.getId()));
        if (emp1.getExprList() != null && !emp1.getExprList().isEmpty()) {
            emp1.getExprList().forEach(expr -> expr.setEmpId(emp1.getId()));// 或插入/删除操作
           empExprService.saveBatch(emp1.getExprList());
        }


    }
    @Override
    public List<Emp> selectall() {
        List<Emp> list = list();
        return  list;
    }

    @Override
    public Emp login(Emp emp1) {
//        查询是否存在
      Emp  loginEmp =emp.SelectByUsername(emp1.getUsername());
//        判断用户名是否存在
        if(loginEmp==null){
            throw new UsernotexistException("用户名不存在");
        }
//        if(!Objects.equals(loginEmp.getPassword(),emp1.getPassword())){
//            throw new UsernotexistException("用户名或密码错误");
//        }
        if(!bCryptUtil.checkPassword(emp1.getPassword(),loginEmp.getPassword())){
            throw new UsernotexistException("用户名或密码错误");
        }
        return loginEmp;
    }
}
